namespace SimpleWebServices.Net
{
    using System;
    using System.Globalization;
    using System.Xml.XPath;

    public sealed class HtmlXpathEvaluateTest<T> : HtmlXpathTest, ITestHttpExpectation
    {
        public HtmlXpathEvaluateTest(T expected, string xpath)
            : this(expected, XPathExpression.Compile(xpath))
        {
        }

        public HtmlXpathEvaluateTest(T expected, XPathExpression xpath)
            : base(xpath)
        {
            this.Expected = expected;
        }

        public T Expected
        {
            get;
            set;
        }

        public bool Check(Response response)
        {
            return this.Check(response as HtmlResponse);
        }

        private bool Check(HtmlResponse response)
        {
            if (null == response)
            {
                throw new ArgumentNullException("response");
            }

            T actual = (T)response.Html.CreateNavigator().Evaluate(this.Expression);
            if (null == this.Expected)
            {
                if (null != actual)
                {
                    string message = string.Format(CultureInfo.InvariantCulture, "HTML XPath : {0}\r\n expected: (null)\r\n actual: {1}", this.Expression.Expression, actual.ToString());
                    throw new HttpTestException(response, message);
                }
            }
            else if (!this.Expected.Equals(actual))
            {
                string message = string.Format(CultureInfo.InvariantCulture, "HTML XPath : {0}\r\n expected: {1}\r\n actual: {2}", this.Expression.Expression, this.Expected.ToString(), actual.ToString());
                throw new HttpTestException(response, message);
            }

            return true;
        }
    }
}